package com.yami.shop.service.impl;

import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.defipay.api.client.domain.response.CreateOrderResponse;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.model.ShopRecharge;
import com.yami.shop.bean.model.ShopWallet;
import com.yami.shop.bean.model.ShopWalletLog;
import com.yami.shop.bean.param.PayParam;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.bean.SysPayConfig;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.enums.PayType;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.config.FaTPayConfig;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.dao.ShopRechargeMapper;
import com.yami.shop.dao.ShopWalletMapper;
import com.yami.shop.manager.impl.PayManager;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.service.ShopRechargeService;
import com.yami.shop.service.ShopWalletLogService;
import com.yami.shop.service.ShopWalletService;
import com.yami.shop.service.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;

@Slf4j
@Service
public class ShopRechargeServiceImpl extends ServiceImpl<ShopRechargeMapper, ShopRecharge>
    implements ShopRechargeService {
  @Autowired
  private SysConfigService sysConfigService;
  @Autowired
  private FaTPayConfig faTPayConfig;
  @Autowired
  private ShopConfig shopConfig;
  @Autowired
  private PayManager payManager;
  @Autowired
  private ShopWalletMapper shopWalletMapper;
  @Autowired
  private ShopWalletService shopWalletService;
  @Autowired
  private ShopWalletLogService shopWalletLogService;
  @Autowired
  private ShopDetailService shopDetailService;

  @Override
  @Transactional(rollbackFor = Exception.class)
  public ServerResponseEntity<?> doPay(ShopDetail shopDetail, PayParam payParam) {
    SysPayConfig sysPayConfig = sysConfigService.getSysConfigObject(Constant.PAY_SWITCH_CONFIG, SysPayConfig.class);
    String domainName = shopConfig.getDomain().getMultishopDomainName();
    String notifyUrl = domainName + "/shop/pay/notify";
    if (!sysPayConfig.getFatPaySwitch()) {
      throw new YamiShopBindException("yami.order.pay.type.check");
    }
    //生成充值信息
    ShopRecharge recharge = new ShopRecharge();
    recharge.setRechargeMoney(new BigDecimal(payParam.getMoney()));
    recharge.setShopId(shopDetail.getShopId());
    recharge.setCreateDate(LocalDateTime.now());
    this.save(recharge);
    PayInfoDto payInfo = new PayInfoDto();
    payInfo.setPayNo(String.valueOf(recharge.getRechargeId()));
    payInfo.setApiNoticeUrl(notifyUrl);
    payInfo.setPayAmount(recharge.getRechargeMoney().doubleValue());
    payInfo.setReturnUrl(payParam.getReturnUrl());
    CreateOrderResponse response = faTPayConfig.createOrder(payInfo); //发起请求
    ShopRecharge shopRecharge = this.getById(response.getMemberTransNo());
    if (shopRecharge == null) {
      throw new YamiShopBindException("yami.shop.pay.info.update.error");
    }
    shopRecharge.setPlatformNumber(response.getMemberTransNo());
    this.updateById(shopRecharge);
    return ServerResponseEntity.success(response);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void notify(HttpServletRequest request, String xmlData)
      throws WxPayException, AlipayApiException, UnsupportedEncodingException {
    //验签，读取body做验证，修改状态，加流水、金额
    PayInfoResultBO payInfo = payManager.validateAndGetPayInfo(request, PayType.FATPAY, xmlData);
    if (payInfo == null) {
      throw new YamiShopBindException("yami.sign.check");
    }
    ShopRecharge shopRecharge = this.getById(payInfo.getPayNo());
    if (shopRecharge != null) {
      if (payInfo.getPayAmount().doubleValue() != shopRecharge.getRechargeMoney().doubleValue()) {
        throw new YamiShopBindException("yami.sign.check");
      }
      if (shopRecharge.getRechargeState() != 1) {
        shopRecharge.setRechargeState(1);
        this.updateById(shopRecharge);
        QueryWrapper<ShopWallet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id", shopRecharge.getShopId());
        queryWrapper.last("limit 1");
        ShopWallet shopWallet = shopWalletService.getOne(queryWrapper);
        //增加金额、增加流水
        shopWalletMapper.updateAccountAmount(shopRecharge.getShopId(), 1, shopRecharge.getRechargeMoney());
        //增加流水
        ShopWalletLog shopWalletLog = new ShopWalletLog();
        shopWalletLog.setWalletLogId(shopWallet.getShopWalletId());
        shopWalletLog.setShopId(shopRecharge.getShopId());
        shopWalletLog.setOrderNumber(String.valueOf(shopRecharge.getRechargeId()));
        shopWalletLog.setIoType(1);
        shopWalletLog.setAmountType(4);
        shopWalletLog.setChangeAomunt(shopRecharge.getRechargeMoney().doubleValue());
        shopWalletLog.setReason(8);
        shopWalletLog.setCreateTime(new Date());
        shopWalletLogService.save(shopWalletLog);
      }
    }
  }
}
